package fr.enseirbmatmeca.apms.hibernate.dao.impl;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.criterion.Expression;
import org.hibernate.exception.DataException;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import fr.enseirbmatmeca.apms.hibernate.dao.UserDAO;
import fr.enseirbmatmeca.apms.spring.model.User;

/**
 * Implements a strategy to perform complex actions on persistent data.
 * @author bmeurant
 */
public class UserDAOImpl extends HibernateDaoSupport implements UserDAO {

	/**
	 * {@inheritDoc}
	 */
	public boolean checkLogin(String login, String password) {
		if (null == login || null == password) {
			throw new IllegalArgumentException("Login and password are mandatory. Null values are forbidden.");
		}		
		try {
			logger.info("Check user with login: "+login+" and password : [PROTECTED]");
			Session session = getHibernateTemplate().getSessionFactory().getCurrentSession();
			// create a new criteria
			Criteria crit = session.createCriteria(User.class);
			crit.add(Expression.ilike("login_user", login));
			crit.add(Expression.eq("passwordUser", password));
			
			User user = (User)crit.uniqueResult();
			return (user != null);
		}
		catch(DataException e) {
			// Critical errors : database unreachable, etc.
			logger.error("Exception - DataAccessException occurs : "+e.getMessage()
					+" on complete checkLogin().");
			return false;
		}
	}
	
	/**
	 * {@inheritDoc}
	 */
	public User getUser(String login) {
		if (null == login) {
			throw new IllegalArgumentException("Login is mandatory. Null value is forbidden.");
		}
		try {
			logger.info("get User with login: "+login);
			Session session = getHibernateTemplate().getSessionFactory().getCurrentSession();
			// create a new criteria
			Criteria crit = session.createCriteria(User.class);
			crit.add(Expression.eq("login", login));
			
			User user = (User)crit.uniqueResult();
			return user;
		}
		catch(DataAccessException e) {
			// Critical errors : database unreachable, etc.
			logger.error("Exception - DataAccessException occurs : "+e.getMessage()
					+" on complete getUser().");
			return null;
		}
	}

	/**
	 * {@inheritDoc}
	 */
	public User createUser(String login, String password) {
		if (null == login) {
			throw new IllegalArgumentException("Login is mandatory. Null value is forbidden.");
		}
			logger.info("create User with login: "+login);
			User user = new User(login, password);
			Session session = getHibernateTemplate().getSessionFactory().getCurrentSession();
			session.persist(user);
			return user;
	}
	
	/**
	 * {@inheritDoc}
	 */
	public boolean saveUser(User user){
		try {
			logger.info("save User with login: "+user.getLogin());
			HibernateTemplate hib = getHibernateTemplate();
			SessionFactory fact = hib.getSessionFactory();
			Session session = fact.getCurrentSession();
			Transaction tx = session.beginTransaction();
			session.saveOrUpdate(user);
			tx.commit();
			return true;
		}
		catch(DataAccessException e) {
			// Critical errors : database unreachable, etc.
			logger.error("Exception - DataAccessException occurs : "+e.getMessage()
					+" on complete getUser().");
			return false;
		}
	}

	public User getUserFromLogAndAuthToken(String userlogin,String authtoken) {
		if (null == userlogin || null ==  authtoken) {
			throw new IllegalArgumentException("GoogleMessagingID is mandatory. Null value is forbidden.");
		}
		try {
			logger.info("get User with userLogin : "+userlogin);
			Session session = getHibernateTemplate().getSessionFactory().getCurrentSession();
			// create a new criteria
			Criteria crit = session.createCriteria(User.class);
			crit.add(Expression.eq("authToken", authtoken)).add(Expression.eq("login", userlogin));
			
			User user = (User)crit.uniqueResult();
			return user;
		}
		catch(DataAccessException e) {
			// Critical errors : database unreachable, etc.
			logger.error("Exception - DataAccessException occurs : "+e.getMessage()
					+" on complete getUserFromLogAndAuthToken().");
			return null;
		}
    }
    
}